#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
PLC数据处理脚本 - Excel COM版本
功能：使用Excel COM接口直接读取Excel文件，绕过格式兼容性问题
需要安装：pip install pywin32
"""

import pandas as pd
import numpy as np
import os
import sys
from pathlib import Path

# 尝试导入COM接口
try:
    import win32com.client
    COM_AVAILABLE = True
except ImportError:
    COM_AVAILABLE = False
    print("警告：未安装pywin32，请运行：pip install pywin32")

def translate_to_english_name(device_name, param_name):
    """
    将设备名称和参数名称翻译为英文组合名称
    """
    # 设备名称翻译映射
    device_mapping = {
        'MILD炉': 'MILD_FURNACE',
        '工艺曲线设定参数': 'PROCESS_CURVE_PARAMS',
        '1段时间': 'STAGE1_TIME',
        '2段时间': 'STAGE2_TIME', 
        '3段时间': 'STAGE3_TIME',
        '4段时间': 'STAGE4_TIME',
        '5段时间': 'STAGE5_TIME',
        '6段时间': 'STAGE6_TIME',
        '7段时间': 'STAGE7_TIME',
        '8段时间': 'STAGE8_TIME',
        '9段时间': 'STAGE9_TIME',
        '10段时间': 'STAGE10_TIME',
        '11段时间': 'STAGE11_TIME',
        '12段时间': 'STAGE12_TIME',
        '13段时间': 'STAGE13_TIME',
        '1段升始温度': 'STAGE1_START_TEMP',
        '2段升始温度': 'STAGE2_START_TEMP',
        '3段升始温度': 'STAGE3_START_TEMP',
        '4段升始温度': 'STAGE4_START_TEMP',
        '5段升始温度': 'STAGE5_START_TEMP',
        '6段升始温度': 'STAGE6_START_TEMP',
        '7段升始温度': 'STAGE7_START_TEMP',
        '8段升始温度': 'STAGE8_START_TEMP',
        '9段升始温度': 'STAGE9_START_TEMP',
        '10段升始温度': 'STAGE10_START_TEMP',
        '11段升始温度': 'STAGE11_START_TEMP',
        '12段升始温度': 'STAGE12_START_TEMP',
        '13段升始温度': 'STAGE13_START_TEMP'
    }
    
    # 参数名称翻译映射
    param_mapping = {
        '空气换热前实际温度': 'AIR_PREHEAT_ACTUAL_TEMP',
        '空气换热后实际温度': 'AIR_POSTHEAT_ACTUAL_TEMP', 
        '排烟换热前实际温度': 'EXHAUST_PREHEAT_ACTUAL_TEMP',
        '排烟换热后实际温度': 'EXHAUST_POSTHEAT_ACTUAL_TEMP',
        '温度探头1实际温度': 'TEMP_PROBE1_ACTUAL',
        '温度探头2实际温度': 'TEMP_PROBE2_ACTUAL',
        '温度探头3实际温度': 'TEMP_PROBE3_ACTUAL',
        '温度探头4实际温度': 'TEMP_PROBE4_ACTUAL',
        '空气实际压力': 'AIR_ACTUAL_PRESSURE',
        '空气总管实际压力': 'AIR_MAIN_ACTUAL_PRESSURE',
        '空气实际流量': 'AIR_ACTUAL_FLOW',
        '空气总管实际流量': 'AIR_MAIN_ACTUAL_FLOW',
        '烟气回流实际流量': 'FLUE_GAS_RECIRCULATION_ACTUAL_FLOW',
        '燃气实际压力': 'GAS_ACTUAL_PRESSURE',
        '燃气总管实际压力': 'GAS_MAIN_ACTUAL_PRESSURE',
        '燃气实际流量': 'GAS_ACTUAL_FLOW'
    }
    
    # 处理设备名称
    device_en = device_mapping.get(device_name, device_name)
    if device_en == device_name and device_name:
        device_en = device_name.replace('段', 'STAGE').replace('时间', 'TIME').replace('升始温度', 'START_TEMP')
    
    # 处理参数名称  
    param_en = param_mapping.get(param_name, param_name)
    if param_en == param_name and param_name:
        param_en = param_name.replace(' ', '_').upper()
    
    # 组合英文名称
    if device_en and param_en:
        return f"{device_en}_{param_en}".replace(' ', '_').upper()
    elif param_en:
        return param_en
    else:
        return ""

def read_excel_via_com(file_path):
    """
    使用Excel COM接口读取Excel文件
    """
    if not COM_AVAILABLE:
        raise Exception("需要安装pywin32：pip install pywin32")
    
    print("使用Excel COM接口读取文件...")
    
    try:
        # 启动Excel应用程序
        excel = win32com.client.Dispatch("Excel.Application")
        excel.Visible = False  # 不显示Excel窗口
        excel.DisplayAlerts = False  # 不显示警告对话框
        
        # 打开工作簿
        workbook = excel.Workbooks.Open(str(file_path))
        worksheet = workbook.ActiveSheet
        
        # 获取已使用的范围
        used_range = worksheet.UsedRange
        rows = used_range.Rows.Count
        cols = used_range.Columns.Count
        
        print(f"检测到数据范围：{rows}行 x {cols}列")
        
        # 读取所有数据
        data = []
        for row in range(1, rows + 1):
            row_data = []
            for col in range(1, cols + 1):
                cell_value = worksheet.Cells(row, col).Value
                if cell_value is None:
                    cell_value = ""
                row_data.append(str(cell_value))
            data.append(row_data)
        
        # 关闭工作簿和Excel
        workbook.Close(False)
        excel.Quit()
        
        # 创建DataFrame
        if len(data) > 1:
            df = pd.DataFrame(data[1:], columns=data[0])  # 第一行作为列名
        else:
            df = pd.DataFrame(data)
        
        print(f"成功读取数据，共 {len(df)} 行")
        return df
        
    except Exception as e:
        print(f"COM接口读取失败: {e}")
        # 确保Excel进程被关闭
        try:
            excel.Quit()
        except:
            pass
        raise

def manual_merge_fill(df):
    """
    手动处理合并单元格 - 向下填充策略
    """
    print("正在处理可能的合并单元格...")
    
    # 对于所有列，向下填充空值
    for col_idx, col_name in enumerate(df.columns):
        # 先尝试向下填充
        df[col_name] = df[col_name].fillna(method='ffill')
        
        # 手动填充剩余的空值
        for i in range(len(df)):
            current_value = str(df.iloc[i, col_idx]).strip()
            if not current_value or current_value.lower() in ['nan', 'none', '']:
                # 向上查找最近的非空值
                for j in range(i-1, -1, -1):
                    prev_value = str(df.iloc[j, col_idx]).strip()
                    if prev_value and prev_value.lower() not in ['nan', 'none', '']:
                        df.iloc[i, col_idx] = prev_value
                        break
    
    print("合并单元格处理完成")
    return df

def process_plc_data_com(input_file, output_file):
    """
    使用COM接口处理PLC数据
    """
    try:
        print(f"正在处理文件: {input_file}")
        
        # 检查输入文件是否存在
        if not Path(input_file).exists():
            print(f"错误：输入文件 {input_file} 不存在！")
            return False
            
        # 通过COM接口读取
        df = read_excel_via_com(input_file)
        print(f"列名: {list(df.columns)}")
        
        # 处理可能的合并单元格
        df = manual_merge_fill(df)
        
        # 创建新的数据框，复制所有原始数据
        new_df = df.copy()
        
        # 添加英文参数名称列
        english_names = []
        
        print("开始生成英文参数名称...")
        
        for index, row in df.iterrows():
            # 获取设备名称和参数名称
            device_name = ""
            param_name = ""
            address = ""
            
            # 尝试从不同列获取设备名称（通常是第2列）
            if len(df.columns) > 1:
                device_name = str(row.iloc[1]).strip() if pd.notna(row.iloc[1]) else ""
            
            # 尝试从不同列获取参数名称（通常是第3列）
            if len(df.columns) > 2:
                param_name = str(row.iloc[2]).strip() if pd.notna(row.iloc[2]) else ""
            
            # 检查是否有地址列（通常是第5列）
            has_address = False
            if len(df.columns) > 4:
                address = str(row.iloc[4]).strip() if pd.notna(row.iloc[4]) else ""
                has_address = bool(address) and address.lower() not in ['nan', 'none', '']
            
            # 只有在有地址的情况下才生成英文名称
            if has_address and (device_name or param_name):
                english_name = translate_to_english_name(device_name, param_name)
                if index < 5:  # 显示前5个示例
                    print(f"  行{index+1}: '{device_name}' + '{param_name}' -> '{english_name}'")
            else:
                english_name = ""
            
            english_names.append(english_name)
        
        # 在数据框的最后添加英文参数名称列
        new_df['参数英文名称'] = english_names
        
        # 保存到新文件
        new_df.to_excel(output_file, index=False, engine='openpyxl')
        print(f"成功生成新文件: {output_file}")
        print(f"新文件包含 {len(new_df)} 行数据，{len(new_df.columns)} 列")
        
        # 显示生成的英文名称统计
        non_empty_names = [name for name in english_names if name.strip()]
        print(f"\n✅ 生成了 {len(non_empty_names)} 个英文参数名称")
        
        if non_empty_names:
            print("英文名称示例:")
            for i, name in enumerate(non_empty_names[:10]):  # 显示前10个
                print(f"  {i+1}. {name}")
        
        return True
        
    except Exception as e:
        print(f"处理文件时发生错误: {e}")
        import traceback
        traceback.print_exc()
        return False

def main():
    """主函数"""
    # 设置文件路径
    script_dir = Path(__file__).parent
    input_file = script_dir / "加热炉实验室plc数据信息.xlsx"
    output_file = script_dir / "加热炉实验室plc数据信息_处理后.xlsx"
    
    print("=== PLC数据处理脚本 (Excel COM版本) ===")
    print(f"脚本目录: {script_dir}")
    print(f"输入文件: {input_file}")
    print(f"输出文件: {output_file}")
    print()
    
    if not COM_AVAILABLE:
        print("❌ 错误：需要安装pywin32")
        print("💡 请运行：pip install pywin32")
        print("   然后重新运行此脚本")
        sys.exit(1)
    
    print("✅ Excel COM接口可用")
    print("⚠️ 此版本通过Excel COM接口解决格式兼容性问题")
    print()
    
    # 处理数据
    success = process_plc_data_com(str(input_file), str(output_file))
    
    if success:
        print("\n🎉 数据处理完成！")
        print("✅ 新文件已生成，包含英文参数名称列")
    else:
        print("\n❌ 数据处理失败！")
        sys.exit(1)

if __name__ == "__main__":
    main()